﻿using OF.DistributeService.Core.Common;
using OF.DistributeService.Core.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using OF.DistributeService.Core.Attribute;
using OF.DistributeService.Core;
using System.Collections.ObjectModel;
using System.Web;
using System.Threading;
using ZooKeeperNet;
using System.Web.Http;
using OF.DistributeService.Core.Client;
using OF.DistributeService.Core.Entity.Service;
using OF.DistributeService.Core.Exception;

namespace OF.DistributeService.Server.Service
{    
    public class OFDistributeServiceManager : IDisposable
    {
        private ZookeeperClusterServer clusterServer = null;
        private readonly VesionComparer vesionComparer = new VesionComparer();
        private static Type ApiControllerType = typeof(ApiController);               
        private static Type objectType = typeof(object);
        public static Regex VersionFormatReg = new Regex("^\\d{1,}(.\\d{1,})*$", RegexOptions.Singleline);

        /// <summary>
        /// 获取服务管理器
        /// </summary>
        public static OFDistributeServiceManager GetManager()
        {
            return new OFDistributeServiceManager();
        }


        /// <summary>
        /// OFDistributeService启动注册程序集方法信息到zookeeper
        /// </summary>
        public void Startup()
        {
            var config = AppConfig.Get();
            if (!ZooKeeperProxy.IsValidateNodeName(config.ApplicationName))
            {
                throw new NotCharOrNumberFormatException("ApplicationName:" + config.ApplicationName);
            }
            if (!ZooKeeperProxy.IsValidateNodeName(config.GroupName))
            {
                throw new NotCharOrNumberFormatException("GroupName:" + config.GroupName);
            }

            List<ApiServiceAttrMeta> metaList = new System.Collections.Generic.List<ApiServiceAttrMeta>(100);
            foreach (var assemblyName in config.ServiceAssemblys.Split(';'))
            {
                Assembly assembly = Assembly.Load(assemblyName);
                ParserAssembly(metaList, assembly);
            }
            BatchWriteToZookeeper(metaList);
        }

        private void BatchWriteToZookeeper(List<ApiServiceAttrMeta> metaList)
        {
            clusterServer = new ZookeeperClusterServer();
            clusterServer.PublishService(metaList);
        }
 

        private void ParseAssemblyTypes(List<ApiServiceAttrMeta> metaList, Type[] typeArray)
        {            
            foreach(var type in typeArray)
            {
                if (!ApiControllerType.IsAssignableFrom(type))
                {
                    continue;
                }
                var apiMethodAttrMeta = OFDistributeServiceAttribute.GetApiServiceAttrMeta(type);
                if (apiMethodAttrMeta != null)
                {
                    metaList.Add(apiMethodAttrMeta);
                }
            }
        }
        /// <summary>
        /// 解析程序集接口的所有方法
        /// </summary>
        /// <param name="assembly">程序集实例</param>
        /// <param name="assemblyVersion">程序集版本</param>
        private void ParserAssembly(List<ApiServiceAttrMeta> metaList, Assembly assembly)
        {
            try
            {
                var typeArray = assembly.GetTypes();
                ParseAssemblyTypes(metaList, typeArray);
            }
            catch (System.Reflection.ReflectionTypeLoadException ex)
            {
                Util.LogException("ParserAssembly", ex);
                throw;
            }
        }

        /// <summary>
        /// 释放托管资源
        /// </summary>
        public void Dispose()
        {
            Util.LogInfo("....Unload event occur, Dipose OFDistributeServiceRegisterCenter begin!");
            if (clusterServer != null)
            {
                clusterServer.Dispose();
                clusterServer = null;
            }
            Util.LogInfo("....Unload event occur, Dipose OFDistributeServiceRegisterCenter end!");
        }	
    }
}